package com.koron.housing.workflow;

import cn.hutool.core.collection.CollUtil;
import com.koron.bean.base.Response;
import com.koron.bean.system.org.OrgBean;
import com.koron.bean.system.post.query.PostUserQuery;
import com.koron.bean.workflow.SubmitterParam;
import com.koron.bean.workflow.WorkflowUser;
import com.koron.common.core.business.common.mapper.StaffMapper;
import com.koron.common.core.business.system.feign.SystemFeignService;
import com.koron.common.core.business.workflow.bean.dto.WorkflowStaff;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jzp
 * @since 2022/1/18
 */
@Component
@Slf4j
public class StaffHelper {

    @Autowired
    private SystemFeignService systemFeignService;

    /**
     * 根据插件人员获取查询条件
     */
    public List<WorkflowUser> getPostUserQuery(List<WorkflowUser> users, PostUserQuery postUserQuery) {
        if (postUserQuery == null) {
            postUserQuery = new PostUserQuery();
        }
        if (CollUtil.isEmpty(postUserQuery.getPostIdList())) {
            postUserQuery.setPostIdList(new ArrayList<>());
        }
        if (CollUtil.isEmpty(postUserQuery.getParentOrgIdList())) {
            postUserQuery.setParentOrgIdList(new ArrayList<>());
        }

        List<WorkflowUser> results = new ArrayList<>();

        if (CollUtil.isNotEmpty(users)) {
            // 人员信息
            users.stream().filter(item -> item.getType() == 0).forEach(results::add);

            // 部门信息
            List<String> orgIdList = postUserQuery.getParentOrgIdList();
            users.stream().filter(item -> item.getType() == 1).forEach(e -> orgIdList.add(e.getCode()));

            // 岗位信息
            List<String> postIdList = postUserQuery.getPostIdList();
            users.stream().filter(item -> item.getType() == 2).forEach(e -> postIdList.add(e.getCode()));
        }
        // 查询所有插件人员信息并返回
        Optional.ofNullable(systemFeignService.queryPostList(postUserQuery))
                .map(Response::getData)
                .ifPresent(list -> {
                    list.forEach(datum -> results.add(new WorkflowUser(datum.getUserAccount(), datum.getUserName())));
                });
        return results;
    }

    /**
     * 根据账号查询其所在部门
     */
    public List<WorkflowUser> getOrgByAccount(String account) {
        try (SessionFactory factory = new SessionFactory()) {
            factory.setDbEnv("_default");
            StaffMapper mapper = factory.getMapper(StaffMapper.class);
            List<WorkflowStaff> workflowStaffs = mapper.selectStaffOrg(Collections.singletonList(account));
            Assert.state(!CollectionUtils.isEmpty(workflowStaffs) && workflowStaffs.size() == 1, "编制人不能为空，且只能有一个");
            WorkflowStaff workflowStaff = workflowStaffs.get(0);
            // 一个人可能属于多个部门
            Map<String, OrgBean> map = new HashMap<>();
            String[] split = workflowStaff.getOrgId().split(",");
            for (String orgId : split) {
                OrgBean dept = systemFeignService.queryDeptByOrgId(orgId).getData();
                if (dept != null) {
                    map.putIfAbsent(dept.getId(), dept);
                }
            }
            return map.values().stream().map(dept -> new WorkflowUser(dept.getName(), dept.getId(), 1)).collect(Collectors.toList());
        }
    }

    /**
     * 交符号是∩,并符号是∪
     * [岗位的人员 ∪ 岗位的人员] ∩ [部门的人员 ∪ 部门的人员] ∪ [人员]
     */
    public List<WorkflowUser> mixed(List<WorkflowUser> users) {
        List<WorkflowUser> results = new ArrayList<>();
        if (!CollectionUtils.isEmpty(users)) {
            // 取出所有岗位的人并取并集
            List<WorkflowUser> postList = users.stream().filter(e -> e.getType() == 2).map(user -> getPostUserQuery(Collections.singletonList(user), null)).flatMap(Collection::stream).collect(Collectors.toList());

            // 取出所有部门的人并取并集
            List<WorkflowUser> deptList = users.stream().filter(e -> e.getType() == 1).map(user -> getPostUserQuery(Collections.singletonList(user), null)).flatMap(Collection::stream).collect(Collectors.toList());

            // 岗位和部门取交集
            results = intersectionUser(Arrays.asList(postList, deptList));

            // 和所有的单独人员取并集
            results.addAll(users.stream().filter(e -> e.getType() == 0).collect(Collectors.toList()));
        }

        return results;
    }

    /**
     * 添加编制人所在部门
     */
    public void fillAuthorizerOrg(SubmitterParam submitterParam, String authorizer) {
        List<WorkflowUser> users = submitterParam.getUsers();
        if (CollectionUtils.isEmpty(users)) {
            users = new ArrayList<>();
            submitterParam.setUsers(users);
        }
        users.addAll(getOrgByAccount(authorizer));
    }

    // 多坨人员之间取交集，组织和岗位会剔除掉
    public List<WorkflowUser> intersectionUser(List<List<WorkflowUser>> users) {
        log.info("所有人员取交集：{}", users);
        return users.stream().filter(e -> !CollectionUtils.isEmpty(e)).reduce((a, b) -> {
            a.removeIf(e -> e.getType() != 0);
            if (a.size() == 0) {
                return b;
            }
            a.retainAll(b);
            return a;
        }).orElse(new ArrayList<>());
    }

}
